home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-02 / cwtpu.zip / CWARE.PAS < prev    next >
Pascal/Delphi Source File  |  1993-01-04  |  15KB  |  463 lines

  1. {$A+,B-,D+,E-,F+,I-,L+,N-,O+,R-,S+,V-}
  2.  
  3. Unit CWare;
  4.  
  5. (* Version 1.0 - CollisionWare Premium SoftWare - Compiled by Kito Mann *)
  6. (* This unit is a simple collection of some some procedures aquired     *)
  7. (* from other programs and myself. New versions will have added         *)
  8. (* procedures, and the present ones will be improved. Comments, bugs,   *)
  9. (* and questions accepted.                                              *)
  10. (* Keep in mind that there is NO WARANTY! It IS NOT GAURANTEED that all *)
  11. (* these procedures will work!                                          *) 
  12. (* If you modify the procedures included, or add your own, I request    *)
  13. (* that you send me a copy of the new unit and source code.             *)
  14.  
  15. (* It'd probably be helpful if you declare ErrorCode: byte in your main *)
  16. (* program. It is used as an Error variable much like the DosError used *)
  17. (* in the DOS unit.                                                     *)
  18.  
  19. (* The Collision Theory pm-BBS *)
  20. (*         10PM-7AM            *)
  21. (*      (703)425-4674          *)
  22. (*         Burke, VA           *)
  23. (* "Dedicated to Intelligent   *)
  24. (*        Conversation"        *)
  25.  
  26. INTERFACE
  27.  
  28. Uses Crt,
  29.      Dos;
  30.  
  31. const
  32.   MaxDirEnteries=       20;    { Maximum number of directories that can be specified to search }
  33.                                { This doesn't include those searched "below" ones specified.   }
  34.  
  35. type
  36.   FullNameStr=          string[12];                 { Type for storing name+dot+extention                                 }
  37.   DirSearchEntry=       record                      { This data type is used to store all the paths that will be searched }
  38.                           Dir:         DirStr;      {   <-- Path to search                                                }
  39.                           Name:        FullNameStr; {   <-- File spec to search                                           }
  40.                           Below:       boolean;     {   <-- TRUE=search directories below the specified one               }
  41.                         end;
  42.   ProcType=             procedure(var S: SearchRec; P: PathStr);
  43.   AnyStr=               string[255];
  44.  
  45.  
  46. var
  47.   EngineMask:           FullNameStr;
  48.   EngineAttr:           byte;
  49.   EngineProc:           ProcType;
  50.   EngineCode:           byte;
  51.  
  52.   Reg:                  Registers;   { Register storage for DOS calls }
  53.   OldSeg,OldOfs:        word;
  54.   BufData:              longint;
  55.   BufferSeg:            word;
  56.   BufferOfs:            word;
  57.   BufferLen:            word;
  58.   BufferPtr:            pointer;
  59.   T:                    text;
  60.   P:                    PathStr;
  61.  
  62. (* The following procedures are from A2Z by Ian Mclean *)
  63.  
  64. function FileFound(F: ComStr): boolean;
  65.  
  66. function DateString: string;
  67.  
  68. function TimeString: string;
  69.  
  70. procedure SearchEngine(Mask: PathStr; Attr: byte; Proc: ProcType; var ErrorCode: byte);
  71.  
  72. function GoodDirectory(S: SearchRec): boolean;
  73.  
  74. procedure SearchOneDir(var S: SearchRec; P: PathStr);
  75.  
  76. procedure SearchEngineAll(Path: PathStr; Mask: FullNameStr; Attr: byte;
  77.                           Proc: ProcType; var ErrorCode: byte);
  78.  
  79. procedure IPP;
  80.  
  81. procedure NewExitProc2;
  82.  
  83. procedure ResetBuffer;
  84.  
  85. function BufSize: word;
  86.  
  87. function InBuffer(S: string): integer;
  88.  
  89. procedure InstallInterruptHandler;
  90.  
  91. procedure DeleteFiles(P: string);
  92.  
  93. procedure DeleteDir(P:string);
  94.  
  95. procedure Tab(s1,s2:AnyStr; i:integer);
  96.  
  97. function Strr(i:LongInt): AnyStr;
  98.  
  99. function UpCaseString(st:AnyStr): AnyStr;
  100.  
  101. procedure ListFiles(P: string; complete:boolean; pausenum:integer);
  102.  
  103. IMPLEMENTATION
  104.  
  105. function FileFound(F: ComStr): boolean;
  106. {
  107.   This returns TRUE if the file F exists, FALSE otherwise.  F can contain
  108.   wildcard characters.
  109. }
  110. var
  111.   SRec:                 SearchRec;
  112. begin
  113.   SRec.Name := '*';
  114.   FindFirst(F,0,SRec);
  115.   if SRec.Name='*' then FileFound := false else FileFound := true;
  116. end;
  117.  
  118.  
  119.   function DateString: string;
  120.   {
  121.     Returns the current date in a string of the form:  MON ## YEAR.
  122.     E.g, 21 Feb 1989 or 02 Jan 1988.
  123.   }
  124.   const
  125.     Month:              array[1..12] of string[3]=
  126.                         ('Jan','Feb','Mar','Apr','May','Jun',
  127.                          'Jul','Aug','Sep','Oct','Nov','Dec');
  128.   var
  129.     Y,M,D,Junk:         word;
  130.     DS,YS:              string[5];
  131.   begin
  132.     GetDate(Y,M,D,Junk);
  133.     Str(Y,YS);
  134.     Str(D,DS);
  135.     if length(DS)<2 then DS := '0'+DS;
  136.     DateString := DS+' '+Month[M]+' '+YS;
  137.   end;
  138.  
  139.   function TimeString: string;
  140.   {
  141.     Returns the current time in the form:  HH:MM am/pm
  142.     E.g, 12:00 am or 09:12 pm.
  143.   }
  144.   var
  145.     H,M,Junk:           word;
  146.     HS,MS:              string[5];
  147.     Am:                 boolean;
  148.   begin
  149.     GetTime(H,M,Junk,Junk);
  150.     case H of
  151.       0:     begin
  152.                Am := true;
  153.                H := 12;
  154.              end;
  155.       1..11: Am := true;
  156.       12:    Am := false;
  157.       else   begin
  158.                Am := false;
  159.                H := H-12;
  160.              end;
  161.     end;
  162.     Str(H,HS);
  163.     Str(M,MS);
  164.     if length(HS)<2 then HS := '0'+HS;
  165.     if length(MS)<2 then MS := '0'+MS;
  166.     if Am then TimeString := HS+':'+MS+' am'
  167.     else TimeString := HS+':'+MS+' pm';
  168.   end;
  169.  
  170. (********* The following search engine routines are sneakly swiped *********)
  171. (********* from Turbo Technix v1n6.  See there for further details *********)
  172.  
  173. procedure SearchEngine(Mask: PathStr; Attr: byte; Proc: ProcType;
  174.                        var ErrorCode: byte);
  175. var
  176.   S:                    SearchRec;
  177.   P:                    PathStr;
  178.   Ext:                  ExtStr;
  179. begin
  180.   FSplit(Mask, P, Mask, Ext);
  181.   Mask := Mask+Ext;
  182.   FindFirst(P+Mask,Attr,S);
  183.   if DosError<>0 then
  184.   begin
  185.     ErrorCode := DosError;
  186.     exit;
  187.   end;
  188.   while DosError=0 do
  189.   begin
  190.     Proc(S, P);
  191.     FindNext(S);
  192.   end;
  193.   if DosError=18 then ErrorCode := 0
  194.   else ErrorCode := DosError;
  195. end;
  196.  
  197. function GoodDirectory(S: SearchRec): boolean;
  198. begin
  199.   GoodDirectory := (S.name<>'.') and (S.Name<>'..') and
  200.   (S.Attr and Directory=Directory);
  201. end;
  202.  
  203. procedure SearchOneDir(var S: SearchRec; P: PathStr);
  204. begin
  205.   if GoodDirectory(S) then
  206.   begin
  207.     P := P+S.Name;
  208.     SearchEngine(P+'\'+EngineMask,EngineAttr,EngineProc,EngineCode);
  209.     SearchEngine(P+'\*.*',Directory or Archive, SearchOneDir,EngineCode);
  210.   end;
  211. end;
  212.  
  213. procedure SearchEngineAll(Path: PathStr; Mask: FullNameStr; Attr: byte;
  214.                           Proc: ProcType; var ErrorCode: byte);
  215. begin
  216.   EngineMask := Mask;
  217.   EngineProc := Proc;
  218.   EngineAttr := Attr;
  219.   SearchEngine(Path+Mask,Attr,Proc,ErrorCode);
  220.   SearchEngine(Path+'*.*',Directory or Archive,SearchOneDir,ErrorCode);
  221.   ErrorCode := EngineCode;
  222. end;
  223.  
  224. (************** Thus ends the sneakly swiped code *************)
  225.  
  226. procedure IPP;
  227. { Interrupt pre-processor.  This is a new handler for interrupt 29h which
  228.   provides special functions.  See comments in IHAND.ASM}
  229. begin
  230.   InLine(
  231.       $06/                   {          push    es                      }
  232.       $1E/                   {          push    ds                      }
  233.       $53/                   {          push    bx                      }
  234.       $57/                   {          push    di                      }
  235.       $BB/$3F/$3F/           {          mov     bx, 3f3fh               }
  236.       $8E/$C3/               {          mov     es, bx                  }
  237.       $BB/$3F/$3F/           {          mov     bx, 3f3fh               }
  238.       $26/$8B/$3F/           {          mov     di, word ptr [es:bx]    }
  239.       $26/$8E/$5F/$02/       {          mov     ds, word ptr [es:bx+2]  }
  240.       $88/$05/               {          mov     byte ptr [di], al       }
  241.       $26/$FF/$07/           {          inc     word ptr [es:bx]        }
  242.       $5F/                   {          pop     di                      }
  243.       $5B/                   {          pop     bx                      }
  244.       $1F/                   {          pop     ds                      }
  245.       $07/                   {          pop     es                      }
  246.       $3C/$0A/               {          cmp     al, 10                  }
  247.       $75/$28/               {          jne     looper                  }
  248.       $50/                   {          push    ax                      }
  249.       $52/                   {          push    dx                      }
  250.       $51/                   {          push    cx                      }
  251.       $53/                   {          push    bx                      }
  252.       $B4/$03/               {          mov     ah, 3                   }
  253.       $B7/$00/               {          mov     bh, 0                   }
  254.       $CD/$10/               {          int     10h                     }
  255.       $80/$FE/$18/           {          cmp     dh, 24                  }
  256.       $75/$15/               {          jne     popper                  }
  257.       $FE/$CE/               {          dec     dh                      }
  258.       $B7/$00/               {          mov     bh, 0                   }
  259.       $B4/$02/               {          mov     ah, 2                   }
  260.       $CD/$10/               {          int     10h                     }
  261.       $B8/$01/$06/           {          mov     ax, 0601h               }
  262.       $B7/$07/               {          mov     bh, 7                   }
  263.       $B9/$00/$11/           {          mov     cx, 1100h               }
  264.       $BA/$4F/$18/           {          mov     dx, 184fh               }
  265.       $CD/$10/               {          int     10h                     }
  266.       $5B/                   {  popper: pop     bx                      }
  267.       $59/                   {          pop     cx                      }
  268.       $5A/                   {          pop     dx                      }
  269.       $58/                   {          pop     ax                      }
  270.       $9C/                   {  looper: pushf                           }
  271.       $9A/$00/$00/$00/$00/   {          call    far [0:0]               }
  272.       $CF);                  {          iret                            }
  273. end;
  274.  
  275.  
  276. procedure NewExitProc2;
  277. { This exit procedure removes the interrupt 29h handler from memory and places
  278.   the cursor at the bottom of the screen. }
  279. begin
  280.   Reg.AH := $25;
  281.   Reg.AL := $29;
  282.   Reg.DS := OldSeg;
  283.   Reg.DX := OldOfs;
  284.   MsDos(Reg);
  285.   Window(1,1,80,25);
  286.   GotoXY(1,24);
  287.   TextAttr := $07;
  288.   ClrEol;
  289. end;
  290.  
  291. procedure ResetBuffer;
  292. { Reset pointers to the text buffer, effectivly deleting any text in it }
  293. begin
  294.   MemW[seg(BufData):ofs(BufData)] := BufferOfs;    { Set first 2 bytes of BufData to point to buffer offset }
  295.   MemW[seg(BufData):ofs(BufData)+2] := BufferSeg;  { And next two bytes to point to buffer segment }
  296.   MemW[seg(IPP):ofs(IPP)+21] := seg(BufData);    { Now point the interrupt routine to BufData for pointer }
  297.   MemW[seg(IPP):ofs(IPP)+26] := ofs(BufData);    {  to the text buffer }
  298. end;
  299.  
  300. function BufSize: word;
  301. { This returns the number of characters in the text buffer.  It's what BufData
  302.   now points to minus what is origionally pointed to, eg, the number of times
  303.   IPP incremented it }
  304. begin
  305.   BufSize := MemW[seg(BufData):ofs(BufData)]-BufferOfs;
  306. end;
  307.  
  308. function InBuffer(S: string): integer;
  309. { This searched the text buffer for the string S, and if it's found returns
  310.   the offset in the buffer.  If it's not found a -1 is returned }
  311. var
  312.   L,M:                  word;
  313.   X:                    byte;
  314. begin
  315.   X := 1;
  316.   L := BufferOfs;
  317.   M := BufSize;
  318.   while (X<=length(S)) and (L<=M) do
  319.   begin
  320.     if Mem[BufferSeg:L]=byte(S[X]) then Inc(X) else X := 1;
  321.     Inc(L);
  322.   end;
  323.   if X>length(S) then InBuffer := L-length(S) else InBuffer := -1;
  324. end;
  325.  
  326. procedure InstallInterruptHandler;
  327. { Installs the int 29h handler }
  328. begin
  329.   BufferLen := $4000;  { Set up a 16k buffer }
  330.   GetMem(BufferPtr,BufferLen);  { Allocate memory pointed at by BufferPtr }
  331.   BufferSeg := seg(BufferPtr^);  { Read segment and offset of buffer for easy access }
  332.   BufferOfs := ofs(BufferPtr^);
  333.   ResetBuffer;    { Place these values in the IPP routine, resetting buffer }
  334.   Reg.AH := $35;
  335.   Reg.AL := $29;  { DOS service 35h, get interrupt vector for 29h }
  336.   MsDos(Reg);
  337.   OldSeg := Reg.ES;   { Store the segment and offset of the old vector for later use }
  338.   OldOfs := Reg.BX;
  339.   MemW[seg(IPP):ofs(IPP)+90] := Reg.BX;  { And store them so IPP can call the routine }
  340.   MemW[seg(IPP):ofs(IPP)+92] := Reg.ES;
  341.   Reg.AL := $29; { DOS service 25h, set interrupt vector 29h }
  342.   Reg.AH := $25;
  343.   Reg.DS := seg(IPP);    { Store segment and offset for IPP.  The +16 is to skip TP stack }
  344.   Reg.DX := ofs(IPP)+16; { maintainence routines }
  345.   MsDos(Reg);
  346. end;
  347.  
  348. { Next two procedures slightly modifed }
  349.  
  350.   procedure DeleteFiles(P: string);
  351.   {
  352.     Delete all files in the directory named, including
  353.     Hidden, Read-only, System and other file types.
  354.   }
  355.   var
  356.     SRec:               SearchRec;
  357.     ErrorCode:          byte;
  358.   begin
  359.     FindFirst(P+'\*.*',0,SRec);
  360.     while DosError=0 do
  361.     begin
  362.       Assign(T, P+'\'+SRec.Name);
  363.       SetFAttr(T,Archive);
  364.       writeln('Deleting ',P,+'\'+Srec.Name);
  365.       {$I-}
  366.       Erase(T);
  367.       {$I+}
  368.       ErrorCode := IOResult;
  369.       FindNext(SRec);
  370.     end;
  371.     ErrorCode := IOResult;
  372. end;
  373.  
  374. procedure DeleteDir(P:string);
  375.  
  376. { Simply deletes specified directory }
  377.  
  378. var ErrorCode: byte;
  379. begin
  380.   DeleteFiles(P);
  381.   {$I-}
  382.   RmDir(P);
  383.   {$I+}
  384.   ErrorCode := IOResult;
  385. end;
  386.  
  387. (* The following procedures NOT from A2Z, but from Kito D. Mann *)
  388.  
  389. procedure Tab(s1,s2:AnyStr; i:integer);
  390.  
  391. { Writes s1, then goes to i-length(s1) and writes s2 }
  392.  
  393. var j,k:integer;
  394. begin
  395.   j:=length(s1);
  396.   i:=i-j;
  397.   write(s1);
  398.   for k:=1 to i do write(' ');
  399.   write(s2);
  400. end;
  401.  
  402. function Strr(i:longint): AnyStr;
  403.  
  404. { Converts an integer to string }
  405.  
  406. var outcome:AnyStr;
  407. begin
  408.   str(i,outcome);
  409.   Strr:=outcome;
  410. end;
  411.  
  412. function UpCaseString(st:AnyStr): AnyStr;
  413.  
  414. { Converts a string to all upcase chars }
  415.  
  416. var i:integer; {st2:AnyStr;}
  417. begin
  418.    for i:=1 to length(st) do st[i]:=UpCase(st[i]);
  419.    UpCaseString:=st;
  420. end;
  421.  
  422. procedure ListFiles(P: string; complete:boolean; pausenum:integer);
  423.   {
  424.    If complete is true then will show the name and file size of every
  425.    file. Otherwise will just show the filename. Numlines is the number
  426.    of files it will display before a pause. 0 means no pause.
  427.   }
  428.   var
  429.     SRec:               SearchRec;
  430.     ErrorCode:          byte;
  431.     Size:               AnyStr;
  432.     Index:              integer;
  433.     TheChar:            char;
  434.     Quit:               boolean;
  435.  
  436.   begin
  437.     Quit:=false;
  438.     FindFirst(P+'\*.*',0,SRec);
  439.     Index:=1;
  440.     while DosError=0 do
  441.     begin
  442.        if Index=pausenum then 
  443.        begin
  444.         write('[Q=quit, ANY KEY=continue]:');
  445.         TheChar:=ReadKey;
  446.         if UpCase(TheChar)='Q' then quit:=true;
  447.         writeln;
  448.         Index:=0;
  449.        end;
  450.       if NOT Quit then 
  451.       if complete then begin
  452.         Size:=strr(Srec.Size);
  453.         tab(Srec.Name,Size,15);
  454.         writeln;
  455.       end else
  456.       writeln(Srec.Name);
  457.       FindNext(SRec);
  458.       Inc(Index);
  459.     end;
  460.     ErrorCode := IOResult;
  461. end;
  462.  
  463. end.